/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { ArkFile, AstTreeUtils, ts } from "arkanalyzer";
import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger';
import { FileMatcher, MatcherCallback, MatcherTypes } from "../../matcher/Matchers";
import { Defects, IssueReport } from "../../model/Defects";
import { Rule } from "../../model/Rule";
import { BaseChecker, BaseMetaData } from "../BaseChecker";
import { RuleListUtil } from "../../utils/common/DefectsList";
import { RuleFix } from "../../model/Fix";

const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'PreferArrowCallbackCheck');

interface Violation {
    line: number;
    character: number;
    message: string;
    suggestion: string;
    node: ts.Node
}

type Option = [{
    allowNamedFunctions?: boolean;
    allowUnboundThis?: boolean;
}];

export class PreferArrowCallbackCheck implements BaseChecker {
    public rule: Rule;
    public defects: Defects[] = [];
    public issues: IssueReport[] = [];
    public metaData: BaseMetaData = {
        severity: 2,
        ruleDocPath: 'docs/prefer-arrow-callback-check.md',
        description: 'Prefer arrow functions for callbacks.',
    };

    private fileMatcher: FileMatcher = {
        matcherType: MatcherTypes.FILE,
    };

    public registerMatchers(): MatcherCallback[] {
        const fileMatcher: MatcherCallback = {
            matcher: this.fileMatcher,
            callback: this.check,
        };
        return [fileMatcher];
    }

    private defaultOptions: Option = [{}];

    public check = (target: ArkFile) => {
        if (target instanceof ArkFile) {
            let code = target.getCode();
            const myInvalidPositions = this.checkAction(code, target);
            myInvalidPositions.forEach((violation) => {
                const filePath = target.getFilePath() ?? "";
                let defect = this.addIssueReport(violation, filePath);
                let ruleFix = this.createFix(violation?.node, violation?.suggestion);
                this.issues.push(new IssueReport(defect, ruleFix));
            });
        }
    };

    private checkAction(sourceCode: string, arkFile: ArkFile): Violation[] {
        const sourceFile = AstTreeUtils.getASTNode(arkFile.getName(), sourceCode); // 获取AST节点
        const violations: Violation[] = [];
        this.defaultOptions = this.rule && this.rule.option[0] ? this.rule.option as Option : [{ allowUnboundThis: true }];
        const allowNamedFunctions = this.defaultOptions[0].allowNamedFunctions === true; // 是否允许具名函数
        const allowUnboundThis = this.defaultOptions[0].allowUnboundThis === true; // 是否允许函数内部使用未绑定的 this
        function checkNode(node: ts.Node): void {
            if (!node) {
                return;
            }
            if ((ts.isCallExpression(node) || ts.isNewExpression(node)) && node.arguments) {
                for (const arg of node.arguments) {
                    if (ts.isArrowFunction(arg)) {
                        return
                    }
                    if (ts.isConditionalExpression(arg)) {
                        // 检测三元表达式的 true 和 false 分支
                        if (ts.isFunctionExpression(arg.whenTrue) || ts.isCallExpression(arg.whenTrue)) {
                            canBeReplacedWithArrowFunction(arg.whenTrue, violations, sourceFile, allowNamedFunctions, allowUnboundThis);
                        }
                        if (ts.isFunctionExpression(arg.whenFalse) || ts.isCallExpression(arg.whenFalse)) {
                            canBeReplacedWithArrowFunction(arg.whenFalse, violations, sourceFile, allowNamedFunctions, allowUnboundThis);
                        }
                    } else if (ts.isBinaryExpression(arg) && arg.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
                        // 检测逻辑或表达式的左右两边
                        if (ts.isFunctionExpression(arg.left) || ts.isCallExpression(arg.left)) {
                            canBeReplacedWithArrowFunction(arg.left, violations, sourceFile, allowNamedFunctions, allowUnboundThis);
                        }
                        if (ts.isFunctionExpression(arg.right) || ts.isCallExpression(arg.right)) {
                            canBeReplacedWithArrowFunction(arg.right, violations, sourceFile, allowNamedFunctions, allowUnboundThis);
                        }
                    } else if (ts.isFunctionExpression(arg) || ts.isCallExpression(arg)) {
                        canBeReplacedWithArrowFunction(arg, violations, sourceFile, allowNamedFunctions, allowUnboundThis);
                    } else {
                        return;
                    }
                }
            }
            // 递归检查子节点
            ts.forEachChild(node, checkNode);
        }
        // 从源文件的根节点开始检查
        checkNode(sourceFile);
        return violations; // 返回所有违规信息
    }

    private addIssueReport(violation: Violation, filePath: string): Defects {
        this.metaData.description = violation.message;
        const severity = this.rule.alert ?? this.metaData.severity;
        const endCharacter = violation.node ? violation.node.getSourceFile().getLineAndCharacterOfPosition(violation.node.getEnd()).character : 0;
        const defect = new Defects(violation.line, violation.character, endCharacter + 1, this.metaData.description, severity,
            this.rule.ruleId, filePath, this.metaData.ruleDocPath, true, false, false);;
        RuleListUtil.push(defect);
        return defect;
    }
    private createFix(child: ts.Node, code: string): RuleFix {
        return { range: [child.getStart(), child.getEnd()], text: code };
    }
}

// 检查函数是否可以替换为箭头函数
function canBeReplacedWithArrowFunction(node: ts.FunctionExpression | ts.CallExpression, violations: Violation[], sourceFile: ts.SourceFile, allowNamedFunctions: boolean, allowUnboundThis: boolean) {
    if (ts.isFunctionExpression(node)) {
        const paramNames = node.parameters.map(param => param.name.getText());
        if (new Set(paramNames).size !== paramNames.length) {
            return;
        }
        if (allowNamedFunctions && node.name) {
            // 如果不允许具名函数，且当前函数是具名函数，则直接返回
            return;
        }
        if (hasThisOrArgumentsOrNewTarget(node) || node.asteriskToken !== undefined || isRecursiveFunction(node)) {
            return
        }
        const functionBody = node.body;
        if (functionBody == undefined) {
            const a = convertToFunction(node)
            const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
            const violation: Violation = {
                message: "Unexpected function expression. ",
                line: line + 1,
                character: character + 1,
                suggestion: convertToFunction(node),
                node: node
            };
            violations.push(violation);
        } else {
            const thisUsage = findThisUsage(functionBody);
            if (!thisUsage) {
                // 函数体中没有使用 `this`，告警
                const a = convertToFunction(node)
                const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                const violation: Violation = {
                    message: "Unexpected function expression. ",
                    line: line + 1,
                    character: character + 1,
                    suggestion: convertToFunction(node),
                    node: node
                };
                violations.push(violation);
            } else {
                // 函数体中使用了 `this`，根据 `this` 的类型判断是否告警
                if (thisUsage.type === "ArrowFunction" || thisUsage.type === "ReturnStatement" || thisUsage.type === "DirectThis") {
                    if (allowUnboundThis) {
                        // 如果 `this` 在箭头函数或 return 语句中，不告警 // 如果 `this` 是直接在函数体中使用的，不告警
                        return;
                    } else {
                        // 如果 `this` 在普通函数表达式中，告警
                        const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                        const violation: Violation = {
                            message: "Unexpected function expression. ",
                            line: line + 1,
                            character: character + 1,
                            suggestion: "",
                            node: node
                        };
                        violations.push(violation);
                    }

                } else if (thisUsage.type === "FunctionExpression") {
                    // 如果 `this` 在普通函数表达式中，告警
                    const a = convertToFunction(node)
                    const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                    const violation: Violation = {
                        message: "Unexpected function expression. ",
                        line: line + 1,
                        character: character + 1,
                        suggestion: convertToFunction(node),
                        node: node

                    };
                    violations.push(violation);
                } else if (thisUsage.type === "CallExpression") {
                    // 如果 `this` 在 CallExpression 中，检查是否绑定了 this
                    const hasBindWithThis = (thisUsage.node as ts.CallExpression)?.arguments.some((arg: ts.Node) => arg.kind === ts.SyntaxKind.ThisKeyword);
                    if (!hasBindWithThis) {
                        // 如果没有绑定 this，告警
                        const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                        const violation: Violation = {
                            message: "Unexpected function expression. ",
                            line: line + 1,
                            character: character + 1,
                            suggestion: "",
                            node: node
                        };
                        violations.push(violation);
                    }
                }
            }
        }
    }
    if (ts.isCallExpression(node)) {
        // 检查是否是 .bind() 调用
        if (ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === "bind") {
            const functionExpression = node.expression.expression;
            const originalFunctionExpression = findOriginalFunctionExpression(functionExpression);
            if (!originalFunctionExpression) {
                return
            }
            if (hasThisOrArgumentsOrNewTarget(node)) {
                return
            }
            if (ts.isPropertyAccessExpression(node.expression.name.parent)) {
                if (node.expression.name.parent) {
                    let b = (node.expression.name.parent.expression as ts.CallExpression).arguments ?? []
                    if (b[0] == undefined) {
                        if (node.arguments.length > 1) {
                            if (ts.isFunctionExpression(functionExpression)) {
                                // 检查函数体中是否使用了 `this`
                                const functionBody = functionExpression.body;
                                if (functionBody == undefined) {
                                    const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                    const violation: Violation = {
                                        message: "Unexpected function expression. ",
                                        line: line + 1,
                                        character: character + 1,
                                        suggestion: convertToArrowFunction(functionExpression, node),
                                        node: node
                                    };
                                    violations.push(violation);
                                } else {
                                    const thisUsage = findThisUsage(functionBody);
                                    if (!thisUsage) {
                                        const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                        const violation: Violation = {
                                            message: "Unexpected function expression. ",
                                            line: line + 1,
                                            character: character + 1,
                                            suggestion: convertToArrowFunction(functionExpression, node),
                                            node: node
                                        };
                                        violations.push(violation);
                                    } else {
                                        // 函数体中使用了 `this`，根据 `this` 的类型判断是否告警
                                        if (thisUsage.type === "ArrowFunction" || thisUsage.type === "ReturnStatement" || thisUsage.type === "DirectThis") {
                                            if (allowUnboundThis) {
                                                // 如果 `this` 在箭头函数或 return 语句中，不告警 // 如果 `this` 是直接在函数体中使用的，不告警
                                                return;
                                            } else {
                                                // 如果 `this` 在普通函数表达式中，告警
                                                const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                                const violation: Violation = {
                                                    message: "Unexpected function expression. ",
                                                    line: line + 1,
                                                    character: character + 1,
                                                    suggestion: convertToArrowFunction(functionExpression, node),
                                                    node: node
                                                };
                                                violations.push(violation);
                                            }

                                        } else if (thisUsage.type === "FunctionExpression") {
                                            // 如果 `this` 在普通函数表达式中，告警
                                            const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                            const violation: Violation = {
                                                message: "Unexpected function expression. ",
                                                line: line + 1,
                                                character: character + 1,
                                                suggestion: convertToArrowFunction(functionExpression, node),
                                                node: node
                                            };
                                            violations.push(violation);
                                        } else if (thisUsage.type === "CallExpression") {
                                            // 如果 `this` 在 CallExpression 中，检查是否绑定了 this
                                            const hasBindWithThis = (thisUsage.node as ts.CallExpression)?.arguments.some((arg: ts.Node) => arg.kind === ts.SyntaxKind.ThisKeyword);
                                            if (!hasBindWithThis) {
                                                // 如果没有绑定 this，告警
                                                const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                                const violation: Violation = {
                                                    message: "Unexpected function expression. ",
                                                    line: line + 1,
                                                    character: character + 1,
                                                    suggestion: convertToArrowFunction(functionExpression, node),
                                                    node: node
                                                };
                                                violations.push(violation);
                                            }
                                        }
                                    }
                                }
                            }
                        } else {
                            if (node.arguments[0].getText().includes("this")) {
                                const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                const violation: Violation = {
                                    message: "Unexpected function expression. ",
                                    line: line + 1,
                                    character: character + 1,
                                    suggestion: convertToArrowFunction(originalFunctionExpression, node),
                                    node: node
                                };
                                violations.push(violation);
                            } else {
                                if (ts.isFunctionExpression(functionExpression)) {
                                    // 检查函数体中是否使用了 `this`
                                    const functionBody = functionExpression.body;
                                    if (functionBody == undefined) {
                                        const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                        const violation: Violation = {
                                            message: "Unexpected function expression. ",
                                            line: line + 1,
                                            character: character + 1,
                                            suggestion: "",
                                            node: node
                                        };
                                        violations.push(violation);
                                    } else {
                                        const thisUsage = findThisUsage(functionBody);
                                        if (!thisUsage) {
                                            // 函数体中没有使用 `this`，告警
                                            const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                            const violation: Violation = {
                                                message: "Unexpected function expression. ",
                                                line: line + 1,
                                                character: character + 1,
                                                suggestion: "",
                                                node: node
                                            };
                                            violations.push(violation);
                                        } else {
                                            // 函数体中使用了 `this`，根据 `this` 的类型判断是否告警
                                            if (thisUsage.type === "ArrowFunction" || thisUsage.type === "ReturnStatement" || thisUsage.type === "DirectThis") {
                                                if (allowUnboundThis) {
                                                    // 如果 `this` 在箭头函数或 return 语句中，不告警 // 如果 `this` 是直接在函数体中使用的，不告警
                                                    return;
                                                } else {
                                                    // 如果 `this` 在普通函数表达式中，告警
                                                    const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                                    const violation: Violation = {
                                                        message: "Unexpected function expression. ",
                                                        line: line + 1,
                                                        character: character + 1,
                                                        suggestion: "",
                                                        node: node
                                                    };
                                                    violations.push(violation);
                                                }

                                            } else if (thisUsage.type === "FunctionExpression") {
                                                // 如果 `this` 在普通函数表达式中，告警
                                                const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                                const violation: Violation = {
                                                    message: "Unexpected function expression. ",
                                                    line: line + 1,
                                                    character: character + 1,
                                                    suggestion: "",
                                                    node: node
                                                };
                                                violations.push(violation);
                                            } else if (thisUsage.type === "CallExpression") {
                                                // 如果 `this` 在 CallExpression 中，检查是否绑定了 this
                                                const hasBindWithThis = (thisUsage.node as ts.CallExpression)?.arguments.some((arg: ts.Node) => arg.kind === ts.SyntaxKind.ThisKeyword);
                                                if (!hasBindWithThis) {
                                                    // 如果没有绑定 this，告警
                                                    const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                                    const violation: Violation = {
                                                        message: "Unexpected function expression. ",
                                                        line: line + 1,
                                                        character: character + 1,
                                                        suggestion: "",
                                                        node: node
                                                    };
                                                    violations.push(violation);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    } else {
                        if (b[0]?.getText().includes("this")) {
                            const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                            const violation: Violation = {
                                message: "Unexpected function expression. ",
                                line: line + 1,
                                character: character + 1,
                                suggestion: convertToArrowFunction(originalFunctionExpression, node),
                                node: node
                            };
                            violations.push(violation);

                        } else {
                            if (originalFunctionExpression && ts.isFunctionExpression(originalFunctionExpression)) {
                                // 检查函数体中是否使用了 `this`
                                const functionBody = originalFunctionExpression.body;
                                if (functionBody == undefined) {
                                    const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                    const violation: Violation = {
                                        message: "Unexpected function expression. ",
                                        line: line + 1,
                                        character: character + 1,
                                        suggestion: "",
                                        node: node
                                    };
                                    violations.push(violation);
                                }
                                else {
                                    const thisUsage = findThisUsage(functionBody);
                                    if (!thisUsage) {
                                        // 函数体中没有使用 `this`，告警
                                        const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                        const violation: Violation = {
                                            message: "Unexpected function expression. ",
                                            line: line + 1,
                                            character: character + 1,
                                            suggestion: "",
                                            node: node
                                        };
                                        violations.push(violation);
                                    } else {
                                        // 函数体中使用了 `this`，根据 `this` 的类型判断是否告警
                                        if (thisUsage.type === "ArrowFunction" || thisUsage.type === "ReturnStatement" || thisUsage.type === "DirectThis") {
                                            if (allowUnboundThis) {
                                                // 如果 `this` 在箭头函数或 return 语句中，不告警 // 如果 `this` 是直接在函数体中使用的，不告警
                                                return;
                                            } else {
                                                // 如果 `this` 在普通函数表达式中，告警
                                                const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                                const violation: Violation = {
                                                    message: "Unexpected function expression. ",
                                                    line: line + 1,
                                                    character: character + 1,
                                                    suggestion: "",
                                                    node: node
                                                };
                                                violations.push(violation);
                                            }

                                        } else if (thisUsage.type === "FunctionExpression") {
                                            // 如果 `this` 在普通函数表达式中，告警
                                            const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                            const violation: Violation = {
                                                message: "Unexpected function expression. ",
                                                line: line + 1,
                                                character: character + 1,
                                                suggestion: "",
                                                node: node
                                            };
                                            violations.push(violation);
                                        } else if (thisUsage.type === "CallExpression") {
                                            // 如果 `this` 在 CallExpression 中，检查是否绑定了 this
                                            const hasBindWithThis = (thisUsage.node as ts.CallExpression)?.arguments.some((arg: ts.Node) => arg.kind === ts.SyntaxKind.ThisKeyword);
                                            if (!hasBindWithThis) {
                                                // 如果没有绑定 this，告警
                                                const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
                                                const violation: Violation = {
                                                    message: "Unexpected function expression. ",
                                                    line: line + 1,
                                                    character: character + 1,
                                                    suggestion: "",
                                                    node: node
                                                };
                                                violations.push(violation);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    function convertToArrowFunction(node: ts.FunctionExpression | ts.ArrowFunction, originNode: ts.Node): string {
        // 提取函数参数及其默认值
        const paramsText = node.parameters.map(param => {
            if (ts.isParameterPropertyDeclaration(param, node.parent)) {
                return param.getText();
            } else {
                return param.name.getText() + (param.initializer ? ` = ${param.initializer.getText()}` : "");
            }
        }).join(", ");

        // 提取函数体文本
        let bodyText: string;
        bodyText = `${node.body.getText()}`;

        // 提取 .bind() 部分
        const bindRegex = /\.bind\([^)]+\)/g;
        const bindMatches = originNode.getText().match(bindRegex);

        if (bindMatches) {
            // 检查第一个 .bind() 的参数是否是 this
            const firstBind = bindMatches[0];
            const isFirstBindThis = firstBind.includes('.bind(this)');
            // 提取后续的 .bind() 调用
            const bindParts = isFirstBindThis ? bindMatches.slice(1) : bindMatches;
            const bindString = bindParts.join('');
            // console.log("提取的 .bind() 部分：", bindString);
            return `(((${paramsText}) => ${bodyText})${bindString})`;
        } else {
            // console.log("未找到 .bind() 调用");
            return `((${paramsText}) => ${bodyText})`;
        }
    }

    function convertToFunction(node: ts.FunctionExpression): string {
        // 提取函数参数及其默认值
        const paramsText = node.parameters.map(param => {
            if (ts.isParameterPropertyDeclaration(param, node.parent)) {
                return param.getText();
            } else {
                return param.name.getText() + (param.initializer ? ` = ${param.initializer.getText()}` : "");
            }
        }).join(", ");

        // 提取函数体文本
        let bodyText: string;

        bodyText = `${node.body.getText()}`;

        // 生成修复后的代码
        return `((${paramsText}) => ${bodyText})`;
    }

    //解析嵌套的 .bind() 调用，找到最初的函数表达式
    function findOriginalFunctionExpression(node: ts.Node): ts.FunctionExpression | ts.ArrowFunction | undefined {
        if (ts.isFunctionExpression(node) || ts.isArrowFunction(node)) {
            // 如果当前节点是函数表达式或箭头函数，直接返回
            return node;
        } else if (ts.isCallExpression(node)) {
            // 如果当前节点是调用表达式，检查其表达式
            return findOriginalFunctionExpression(node.expression);
        } else if (ts.isPropertyAccessExpression(node)) {
            // 如果当前节点是属性访问表达式，检查其表达式
            return findOriginalFunctionExpression(node.expression);
        }
        else if (ts.isParenthesizedExpression(node)) {
            // 如果当前节点是属性访问表达式，检查其表达式
            return findOriginalFunctionExpression(node.expression);
        }
    }
    // 辅助函数：查找函数体中 this 的使用情况

    function findThisUsage(node: ts.Node): { type: string; node?: ts.Node } | null {
        // 直接检测 this
        if (node.kind === ts.SyntaxKind.ThisKeyword) {
            return { type: "DirectThis", node };
        }

        // 检测 this 是否在箭头函数中
        if (ts.isArrowFunction(node)) {
            const thisUsage = ts.forEachChild(node, findThisUsage);
            if (thisUsage) {
                return { type: "ArrowFunction", node };
            }
        }

        // 检测 this 是否在返回语句中
        if (ts.isReturnStatement(node)) {
            const thisUsage = node.expression ? findThisUsage(node.expression) : null;
            if (thisUsage) {
                return { type: "ReturnStatement", node };
            }
        }

        // 检测 this 是否在函数表达式中
        // if (ts.isFunctionExpression(node)) {
        //     const thisUsage = ts.forEachChild(node, findThisUsage);
        //     if (thisUsage) {
        //         return { type: "FunctionExpression", node };
        //     }
        // }
        if (ts.isFunctionExpression(node)) {
            return { type: "FunctionExpression" };
        }

        // 检测 this 是否在调用表达式中
        if (ts.isCallExpression(node)) {
            const thisUsage = ts.forEachChild(node, findThisUsage);
            if (thisUsage) {
                return { type: "CallExpression", node };
            }
        }

        // 检测 this 是否在块中
        if (ts.isBlock(node)) {
            for (const child of node.statements) {
                const thisUsage = findThisUsage(child);
                if (thisUsage) {
                    return thisUsage;
                }
            }
        }
        // 递归检查所有子节点
        return ts.forEachChild(node, findThisUsage) ?? null;
    }

    function hasThisOrArgumentsOrNewTarget(node: ts.Node): boolean {
        if (ts.isIdentifier(node) && node.text === 'arguments') {
            return true;
        }
        if (ts.isMetaProperty(node) && node.getText() === 'new.target') {
            return true;
        }
        return ts.forEachChild(node, hasThisOrArgumentsOrNewTarget) ?? false;
    }

    // 检查是否是递归函数
    function isRecursiveFunction(node: ts.FunctionExpression): boolean {
        const functionName = node.name?.getText();
        if (!functionName) return false;

        const bodyText = node.body?.getText();
        return bodyText?.includes(functionName);
    }


}
